package com.example.AudioPlayBack;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder.AudioSource;
import android.util.Log;

public class Audio extends Thread {
	
	    private boolean stopped = false;
	    private AudioRecord recorder;
	    private AudioTrack track;
	    private int N;
	    private short[][] buffers;
	    private int ix;
	    private short[] buffer;

	    /**
	     * Give the thread high priority so that it's not canceled unexpectedly, and start it
	     */
	    public Audio()
	    { 
	        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
	        
	        init();
	        
	        start();
	    }
	    
	    public void init() {
	    	N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT);
            
            recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_STEREO,
            		AudioFormat.ENCODING_PCM_16BIT, N*10);
            
	        track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, 
	            	AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, N, AudioTrack.MODE_STREAM);
	    }

	    @Override
	    public void run()
	    { 
	        
	        buffers = new short[100][100];
	        ix = 0;

	        /*
	         * Initialize buffer to hold continuously recorded audio data, start recording, and start
	         * playback.
	         */
	        try
	        {
	            recorder.startRecording();
	            
	            track.play();
	            
	            /*
	             * Loops until something outside of this thread stops it.
	             * Reads the data from the recorder and writes it to the audio track for playback.
	             */
	            while(!stopped)
	            {	
	                buffer = buffers[ix++ % buffers.length];
	                N = recorder.read(buffer,0,buffer.length);
	                track.write(buffer, 0, buffer.length);
	            }
	        }
	        catch(Throwable x)
	        { 
	            Log.w("Audio", "Error reading voice audio", x);
	        }
	        /*
	         * Frees the thread's resources after the loop completes so that it can be run again
	         */
	        finally
	        { 
	            recorder.stop();
	            recorder.release();
	            track.stop();
	            track.release();
	        }
	    }

	    /**
	     * Called from outside of the thread in order to stop the recording/playback loop
	     */
	    public void close()
	    { 
	         stopped = true;
	    }
	    
	    /**
	     * Use to set the stereo volume
	     * @param right right volume (0.0 to 1.0)
	     * @param left left volume (0.0 to 1.0)
	     */
	    public void setStereoVolume(float right, float left) {
	    		track.setStereoVolume(right, left);
	    }
}
